use std::collections::HashMap;
use std::str::FromStr;
use std::time::Duration;
use std::{fs, io, path};
extern crate fs_extra;
use crate::config;
use chrono::{Local, NaiveDateTime};
use fs_extra::dir::CopyOptions;
use fs_extra::dir::{copy, move_dir};

pub struct Task {
    pub task_id: String,
    pub config: config::TaskConfig,
    backup: HashMap<String, String>,
}

impl Task {
    pub fn new(task_id: String, task_config_str: String) -> Task {
        let config: config::TaskConfig = match toml::from_str(&task_config_str) {
            Ok(cfg) => cfg,
            Err(err) => panic!("err: {}", err),
        };
        Task {
            task_id,
            config,
            backup: HashMap::new(),
        }
    }
    pub fn init(&self) -> Result<(), io::Error> {
        let dest = format!("{}/{}", self.config.output, self.task_id);
        fs::create_dir(&dest)?;
        fs::create_dir_all(format!("{}/class/components", &dest))?;
        fs::create_dir_all(format!("{}/class/pages", &dest))?;
        fs::create_dir_all(format!("{}/instance/components", &dest))?;
        fs::create_dir_all(format!("{}/instance/pages", &dest))?;
        // fs::create_dir(format!("{}/setting", &dest))?;
        fs::create_dir(format!("{}/stage", &dest))?;
        fs::create_dir(format!("{}/backup", &dest))?;
        fs::create_dir_all(format!("{}/backup/pages", &dest))?;
        fs::create_dir_all(format!("{}/backup/components", &dest))?;
        // fs::create_dir(format!("{}/log", &dest))?;

        fs::write(
            format!("{}/task.config.toml", &dest),
            format!(
                "madp_location = \"{}\"\noutput = \"{}\"\n{}",
                self.config.madp_location,
                self.config.output,
                config::DEFAULT_TASK_CONFIG
            ),
        )?;
        Ok(())
    }
    pub fn run(&mut self) {
        // 检查配置是否合理
        if self.config.class_page.pages.len() != self.config.class_page.names.len() {
            panic!("页面类型配置错误!")
        }
        if self.config.class_component.components.len() != self.config.class_component.names.len() {
            panic!("组件类型配置错误!")
        }
        let components_instance_num = self.config.instance_component.components.len();
        if self.config.instance_component.names.len() != components_instance_num
            || self.config.instance_component.types.len() != components_instance_num
        {
            panic!("组件实例配置错误!")
        }
        let pages_instance_num = self.config.instance_page.pages.len();
        if self.config.instance_page.names.len() != pages_instance_num
            || self.config.instance_page.types.len() != pages_instance_num
        {
            panic!("页面实例配置错误!")
        }
        let dest = format!("{}/{}", self.config.output, self.task_id);
        // let mut backup_map = HashMap::new();
        let class_dir: path::PathBuf = [
            &self.config.madp_location,
            "data/csii-shared/defaultTheme/admin",
        ]
        .iter()
        .collect();
        let instance_dir: path::PathBuf = [
            &self.config.madp_location,
            &format!(
                "data/csii-app-{}/defaultTheme/admin",
                self.config.app_config.app_id
            ),
        ]
        .iter()
        .collect();
        // 解析页面类型配置文件
        let page_class_config_schema_str =
            fs::read_to_string(class_dir.join("pages/config.schema.json")).unwrap();
        let page_class_config_schema =
            serde_json::Value::from_str(&page_class_config_schema_str).unwrap();
        // 解析组件类型配置文件
        let components_class_config_shcema_str =
            fs::read_to_string(class_dir.join("components/config.schema.json")).unwrap();
        let components_class_config_schema =
            serde_json::Value::from_str(&components_class_config_shcema_str).unwrap();
        // 解析页面实例配置文件
        let pages_instance_config_schema_str =
            fs::read_to_string(instance_dir.join("pages/_list.json")).unwrap();
        let pages_instance_config_schema: Vec<config::ComponentListItem> =
            serde_json::from_str(&pages_instance_config_schema_str).unwrap();
        // 解析组件实例配置文件
        let components_instance_config_schema_str =
            fs::read_to_string(instance_dir.join("components/_list.json")).unwrap();
        let components_instance_config_schema: Vec<config::ComponentListItem> =
            serde_json::from_str(&components_instance_config_schema_str).unwrap();
        // 页面类型配置json实体
        let mut page_class_config_schema_copy = page_class_config_schema.clone();
        let mut page_class_enum = page_class_config_schema["properties"]["type"]["enum"]
            .as_array()
            .unwrap()
            .clone();
        let mut page_class_enum_title = page_class_config_schema["properties"]["type"]["options"]
            ["enum_titles"]
            .as_array()
            .unwrap()
            .clone();
        // 组件类型配置json实体
        let mut component_class_config_schema_copy = components_class_config_schema.clone();
        let mut component_class_enum = components_class_config_schema["properties"]["type"]["enum"]
            .as_array()
            .unwrap()
            .clone();
        let mut component_class_enum_title = components_class_config_schema["properties"]["type"]
            ["options"]["enum_titles"]
            .as_array()
            .unwrap()
            .clone();
        // 页面实例配置json实体
        let mut pages_instance_config_schema_copy: Vec<config::PageListItem> = Vec::new();
        for item in pages_instance_config_schema.iter() {
            pages_instance_config_schema_copy.push(config::PageListItem {
                index: String::from(item.index.as_str()),
                src: String::from(item.src.as_str()),
                name: String::from(item.name.as_str()),
                de_type: String::from(item.de_type.as_str()),
            });
        }
        // 组件实例配置json实体
        let mut components_instance_config_schema_copy: Vec<config::ComponentListItem> = Vec::new();
        for item in components_instance_config_schema.iter() {
            components_instance_config_schema_copy.push(config::ComponentListItem {
                index: String::from(item.index.as_str()),
                src: String::from(item.src.as_str()),
                name: String::from(item.name.as_str()),
                de_type: String::from(item.de_type.as_str()),
            });
        }
        // components_instance_config_schema_copy.clone_from(&components_instance_config_schema[0..]);
        // let component_instance_config
        if self.config.class_page.pages.len() > 0 {
            let mut page_class_index = 0;
            // 页面类型配置：复制页面配置文件,修改config.schema.json文件
            for pc in self.config.class_page.pages.clone().into_iter() {
                match pc.find("pages/") {
                    Some(index) => {
                        if index != 0 {
                            self.finish_task("找不到文件,你是不是页面类型配置前面忘记pages/了？")
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是页面类型配置前面忘记pages/了？"),
                };
                let origin_path = class_dir.join(&pc);
                let mut is_new_page = true;
                let mut i = 0;
                for page_schema in page_class_enum.iter() {
                    if &pc == page_schema.as_str().unwrap() {
                        // enum中已存在同名page-schema,修改name
                        is_new_page = false;
                        page_class_enum_title.remove(i);
                        page_class_enum_title.insert(
                            i,
                            serde_json::Value::String(
                                self.config.class_page.names[page_class_index].to_string(),
                            ),
                        );
                        // 备份原文件
                        let backup_path = format!("{}/backup/{}", dest, pc);
                        match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap())
                        {
                            Ok(_) => {
                                let origin_path_str =
                                    origin_path.clone().into_os_string().into_string().unwrap();
                                println!("备份文件{}成功!", origin_path_str);
                                self.backup
                                    .insert(format!("{}/backup/{}", dest, pc), origin_path_str);
                            }
                            Err(err) => panic!("err: {}", err),
                        }
                    }
                    i += 1;
                }
                if is_new_page {
                    // enum中不存在同名page-schema,在enum中追加page,enum_title追加name
                    page_class_enum.push(serde_json::Value::String(pc.clone()));
                    page_class_enum_title.push(serde_json::Value::String(
                        self.config.class_page.names[page_class_index].to_string(),
                    ))
                }
                let from_path = format!("{}/class/{}", dest, pc);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", &from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
                page_class_index += 1;
            }
            page_class_config_schema_copy["properties"]["type"]["enum"] =
                serde_json::Value::Array(page_class_enum);
            page_class_config_schema_copy["properties"]["type"]["options"]["enum_titles"] =
                serde_json::Value::Array(page_class_enum_title);

            // 备份pages/config.schema.json文件
            let config_schema_file = class_dir.join("pages/config.schema.json");
            match fs::copy(
                &config_schema_file,
                format!("{}/backup/pages/config.schema.json", dest),
            ) {
                Ok(_) => {
                    println!("备份pages/config.schema.json成功!");
                    self.backup.insert(
                        format!("{}/backup/pages/config.schema.json", dest),
                        config_schema_file
                            .clone()
                            .into_os_string()
                            .into_string()
                            .unwrap(),
                    );
                }
                Err(err) => self.finish_task(&format!("复制pages/config.schema.json失败: {}", err)),
            }
            // 修改pages/config.schema.json文件
            match fs::write(
                config_schema_file,
                serde_json::to_string_pretty(&page_class_config_schema_copy).unwrap(),
            ) {
                Ok(()) => (),
                Err(err) => self.finish_task(&format!("复制pages/config.schema.json失败: {}", err)),
            };
        }
        if self.config.class_component.components.len() > 0 {
            let mut component_class_index = 0;
            // 页面类型配置：复制页面配置文件,修改config.schema.json文件
            for cc in self.config.class_component.components.clone().into_iter() {
                match cc.find("components/") {
                    Some(index) => {
                        if index != 0 {
                            self.finish_task(
                                "找不到文件,你是不是组件类型配置前面忘记components/了？",
                            )
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是组件类型配置前面忘记components/了？"),
                };
                let origin_path = class_dir.join(&cc);
                let mut is_new_component = true;
                let mut i = 0;
                for component_schema in component_class_enum.iter() {
                    if &cc == component_schema.as_str().unwrap() {
                        // enum中已存在同名page-schema,修改name
                        is_new_component = false;
                        component_class_enum_title.remove(i);
                        component_class_enum_title.insert(
                            i,
                            serde_json::Value::String(
                                self.config.class_component.names[component_class_index]
                                    .to_string(),
                            ),
                        );
                        // 备份原文件
                        let backup_path = format!("{}/backup/{}", dest, cc);
                        match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap())
                        {
                            Ok(_) => {
                                let origin_path_str =
                                    origin_path.clone().into_os_string().into_string().unwrap();
                                println!("备份文件{}成功!", origin_path_str);
                                self.backup
                                    .insert(format!("{}/backup/{}", dest, cc), origin_path_str);
                            }
                            Err(err) => panic!("err: {}", err),
                        }
                    }
                    i += 1;
                }
                if is_new_component {
                    // enum中不存在同名page-schema,在enum中追加page,enum_title追加name
                    component_class_enum.push(serde_json::Value::String(cc.clone()));
                    component_class_enum_title.push(serde_json::Value::String(
                        self.config.class_component.names[component_class_index].to_string(),
                    ))
                }
                let from_path = format!("{}/class/{}", dest, cc);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", &from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
                component_class_index += 1;
            }
            // 复制sub_schema
            for ccs in self.config.class_component.sub_schema.clone().into_iter() {
                match ccs.find("components/") {
                    Some(index) => {
                        if index != 0 {
                            self.finish_task(
                                "找不到文件,你是不是组件类型配置前面忘记components/了？",
                            )
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是页面类型配置前面忘记components/了？"),
                };
                let origin_path = class_dir.join(&ccs);
                let backup_path = format!("{}/backup/{}", dest, ccs);
                if origin_path.is_file() {
                    // 原文件存在,备份
                    match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap()) {
                        Ok(_) => {
                            let origin_path_str =
                                origin_path.clone().into_os_string().into_string().unwrap();
                            println!("备份文件{}成功!", origin_path_str);
                            self.backup
                                .insert(format!("{}/backup/{}", dest, ccs), origin_path_str);
                        }
                        Err(err) => panic!("err: {}", err),
                    }
                }
                // 复制文件
                let from_path = format!("{}/class/{}", dest, ccs);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
            }
            component_class_config_schema_copy["properties"]["type"]["enum"] =
                serde_json::Value::Array(component_class_enum);
            component_class_config_schema_copy["properties"]["type"]["options"]["enum_titles"] =
                serde_json::Value::Array(component_class_enum_title);
            // 备份components/config.schema.json文件
            let config_schema_file = class_dir.join("components/config.schema.json");
            match fs::copy(
                &config_schema_file,
                format!("{}/backup/components/config.schema.json", dest),
            ) {
                Ok(_) => {
                    println!("备份components/config.schema.json文件成功!");
                    self.backup.insert(
                        format!("{}/backup/components/config.schema.json", dest),
                        config_schema_file
                            .clone()
                            .into_os_string()
                            .into_string()
                            .unwrap(),
                    );
                }
                Err(err) => {
                    self.finish_task(&format!("复制components/config.schema.json失败: {}", err))
                }
            }
            // 修改pages/config.schema.json文件
            match fs::write(
                config_schema_file,
                serde_json::to_string_pretty(&component_class_config_schema_copy).unwrap(),
            ) {
                Ok(()) => (),
                Err(err) => {
                    self.finish_task(&format!("复制components/config.schema.json失败: {}", err))
                }
            };
        }
        if self.config.instance_page.pages.len() > 0 {
            let mut page_instance_index = 0;
            for pi in self.config.instance_page.pages.clone().into_iter() {
                match pi.find("pages/") {
                    Some(index) => {
                        if (index) != 0 {
                            self.finish_task("找不到文件,你是不是页面实例配置前面忘记pages/了？")
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是页面实例配置前面忘记pages/了？"),
                };
                let origin_path = instance_dir.join(&pi);
                let mut is_new_page = true;
                let mut i = 0;
                let pi_cp = String::from(&pi);
                for page_item in pages_instance_config_schema.iter() {
                    if pi_cp == page_item.src {
                        is_new_page = false;
                        pages_instance_config_schema_copy.remove(i);
                        pages_instance_config_schema_copy.insert(
                            i,
                            config::PageListItem {
                                index: page_item.index.to_string(),
                                name: self.config.instance_page.names[page_instance_index]
                                    .to_string(),
                                src: page_item.src.to_string(),
                                de_type: self.config.instance_page.types[page_instance_index]
                                    .to_string(),
                            },
                        );
                        // 备份原文件
                        let backup_path = format!("{}/backup/{}", dest, pi);
                        match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap())
                        {
                            Ok(_) => {
                                let origin_path_str =
                                    origin_path.clone().into_os_string().into_string().unwrap();
                                println!("备份文件{}成功!", origin_path_str);
                                self.backup
                                    .insert(format!("{}/backup/{}", dest, pi), origin_path_str);
                            }
                            Err(err) => panic!("err: {}", err),
                        }
                    }
                    i += 1
                }
                if is_new_page {
                    // 新页面
                    pages_instance_config_schema_copy.insert(
                        0,
                        config::PageListItem {
                            index: pi.to_string(),
                            name: self.config.instance_page.names[page_instance_index].to_string(),
                            src: pi.to_string(),
                            de_type: self.config.instance_page.types[page_instance_index]
                                .to_string(),
                        },
                    )
                    // pages_instance_config_schema_copy.append(&mut vec![config::PageListItem {
                    //     index: pi.to_string(),
                    //     name: self.config.instance_page.names[page_instance_index].to_string(),
                    //     src: pi.to_string(),
                    //     de_type: self.config.instance_page.types[page_instance_index].to_string(),
                    // }])
                }
                let from_path = format!("{}/instance/{}", dest, pi);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
                page_instance_index += 1
            }

            // 复制sub_schema
            for pis in self.config.instance_page.sub_schema.clone().into_iter() {
                match pis.find("pages/") {
                    Some(index) => {
                        if index != 0 {
                            self.finish_task("找不到文件,你是不是页面实例配置前面忘记pages/了？")
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是页面实例配置前面忘记pages/了？"),
                };
                let origin_path = instance_dir.join(&pis);
                let backup_path = format!("{}/backup/{}", dest, pis);
                if origin_path.is_file() {
                    // 原文件存在,备份
                    match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap()) {
                        Ok(_) => {
                            let origin_path_str =
                                origin_path.clone().into_os_string().into_string().unwrap();
                            println!("备份文件{}成功!", origin_path_str);
                            self.backup
                                .insert(format!("{}/backup/{}", dest, pis), origin_path_str);
                        }
                        Err(err) => panic!("err: {}", err),
                    }
                }
                // 复制文件
                let from_path = format!("{}/instance/{}", dest, pis);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
            }
            // pages/_list.json文件
            let list_file = instance_dir.join("pages/_list.json");
            match fs::copy(&list_file, format!("{}/backup/pages/_list.json", dest)) {
                Ok(_) => {
                    println!("pages/_list.json成功!");
                    self.backup.insert(
                        format!("{}/backup/pages/_list.json", dest),
                        list_file.clone().into_os_string().into_string().unwrap(),
                    );
                }
                Err(err) => self.finish_task(&format!("pages/_list.json失败: {}", err)),
            }
            // 修改pages/_list.json文件
            match fs::write(
                list_file,
                serde_json::to_string(&pages_instance_config_schema_copy).unwrap(),
            ) {
                Ok(()) => (),
                Err(err) => self.finish_task(&format!("复制pages/_list.json失败: {}", err)),
            };
            // print!("[");
            // for page_config in pages_instance_config_schema_copy {
            //     print!("{},", serde_json::to_string(&page_config).unwrap());
            // }
            // print!("]")
        }
        if self.config.instance_component.components.len() > 0 {
            let mut component_instance_index = 0;
            for ci in self
                .config
                .instance_component
                .components
                .clone()
                .into_iter()
            {
                match ci.find("components/") {
                    Some(index) => {
                        if (index) != 0 {
                            self.finish_task(
                                "找不到文件,你是不是组件实例配置前面忘记components/了？",
                            )
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是组件实例配置前面忘记components/了？"),
                };
                let origin_path = instance_dir.join(&ci);
                let mut is_new_component = true;
                let mut i = 0;
                let ci_cp = String::from(&ci);
                for component_item in components_instance_config_schema.iter() {
                    if ci_cp == component_item.src {
                        is_new_component = false;
                        components_instance_config_schema_copy.remove(i);
                        components_instance_config_schema_copy.insert(
                            i,
                            config::ComponentListItem {
                                index: component_item.index.to_string(),
                                name: self.config.instance_component.names
                                    [component_instance_index]
                                    .to_string(),
                                src: component_item.src.to_string(),
                                de_type: self.config.instance_component.types
                                    [component_instance_index]
                                    .to_string(),
                            },
                        );
                        // 备份原文件
                        let backup_path = format!("{}/backup/{}", dest, ci);
                        match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap())
                        {
                            Ok(_) => {
                                let origin_path_str =
                                    origin_path.clone().into_os_string().into_string().unwrap();
                                println!("备份文件{}成功!", origin_path_str);
                                self.backup
                                    .insert(format!("{}/backup/{}", dest, ci), origin_path_str);
                            }
                            Err(err) => panic!("err: {}", err),
                        }
                    }
                    i += 1
                }
                if is_new_component {
                    // 新组件

                    components_instance_config_schema_copy.insert(
                        0,
                        config::ComponentListItem {
                            index: ci.to_string(),
                            name: self.config.instance_component.names[component_instance_index]
                                .to_string(),
                            src: ci.to_string(),
                            de_type: self.config.instance_component.types[component_instance_index]
                                .to_string(),
                        },
                    )
                }
                let from_path = format!("{}/instance/{}", dest, ci);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
                component_instance_index += 1
            }

            // 复制sub_schema
            for cis in self
                .config
                .instance_component
                .sub_schema
                .clone()
                .into_iter()
            {
                match cis.find("components/") {
                    Some(index) => {
                        if index != 0 {
                            self.finish_task(
                                "找不到文件,你是不是组件类型配置前面忘记components/了？",
                            )
                        }
                    }
                    _ => self.finish_task("找不到文件,你是不是页面类型配置前面忘记components/了？"),
                };
                let origin_path = instance_dir.join(&cis);
                let backup_path = format!("{}/backup/{}", dest, cis);
                if origin_path.is_file() {
                    // 原文件存在,备份
                    match fs::copy(&origin_path, path::PathBuf::from_str(&backup_path).unwrap()) {
                        Ok(_) => {
                            let origin_path_str =
                                origin_path.clone().into_os_string().into_string().unwrap();
                            println!("备份文件{}成功!", origin_path_str);
                            self.backup
                                .insert(format!("{}/backup/{}", dest, cis), origin_path_str);
                        }
                        Err(err) => panic!("err: {}", err),
                    }
                }
                // 复制文件
                let from_path = format!("{}/instance/{}", dest, cis);
                // 复制文件
                match fs::copy(&from_path, origin_path) {
                    Ok(_) => {
                        println!("合并文件{}成功!", from_path);
                    }
                    Err(err) => self.finish_task(&format!("复制文件{}失败:{}", &from_path, err)),
                }
            }
            // 备份components/_list.json文件
            let list_file = instance_dir.join("components/_list.json");
            match fs::copy(&list_file, format!("{}/backup/components/_list.json", dest)) {
                Ok(_) => {
                    println!("备份文件components/_list.json成功!");
                    self.backup.insert(
                        format!("{}/backup/components/_list.json", dest),
                        list_file.clone().into_os_string().into_string().unwrap(),
                    );
                }
                Err(err) => self.finish_task(&format!("复制components/_list.json失败: {}", err)),
            }
            // components/_list.json文件
            match fs::write(
                list_file,
                serde_json::to_string(&components_instance_config_schema_copy).unwrap(),
            ) {
                Ok(()) => (),
                Err(err) => self.finish_task(&format!("复制pages/_list.json失败: {}", err)),
            };
        }
        // 生成备份文件
        let mut files: Vec<String> = Vec::new();
        let mut origins: Vec<String> = Vec::new();
        for (file_name, origin_path) in self.backup.iter() {
            // files.insert(file_name.to_string(), origin_path.to_string());
            files.push(file_name.to_string());
            origins.push(origin_path.to_string());
        }
        let back_up_config = config::BackUp { files, origins };
        let toml_string = toml::to_string(&back_up_config).unwrap();
        fs::write(format!("{}/backup/backup.toml", dest), toml_string).unwrap();
        println!(
            "合并完成!如果你对合并结果不满意,可以通过执行命令 mmerge rollback {} 来回滚操作",
            self.task_id
        );
    }
    fn finish_task(&self, message: &str) {
        match rollback(&self.backup) {
            Ok(_) => panic!("任务执行失败:{},所有操作已回退!", message),
            Err(_) => panic!("任务执行失败:{},回退失败,请手动回退!", message),
        };
    }
    pub fn schedule(&mut self) {
        let start_time = Local::now();
        let publish_time = NaiveDateTime::parse_from_str(
            &self.config.pre_publish_config.time,
            "%Y-%m-%d %H:%M:%S",
        )
        .unwrap()
        .and_local_timezone(start_time.timezone())
        .unwrap();

        let mut start_timestamp = start_time.timestamp_millis();
        let publish_timestamp = publish_time.timestamp_millis();
        println!(
            "定时发版任务已创建！距离发版{}秒",
            publish_time.timestamp() - start_time.timestamp()
        );
        loop {
            if start_timestamp > publish_timestamp {
                println!("开始执行发版任务...");
                self.do_schedule();
                return ();
            }
            start_timestamp += self.config.pre_publish_config.check_unit;
            std::thread::sleep(Duration::from_millis(
                self.config
                    .pre_publish_config
                    .check_unit
                    .try_into()
                    .unwrap(),
            ));
        }
    }
    pub fn do_schedule(&mut self) {
        let publish_dir: path::PathBuf = [&self.config.madp_location, "data/csii-app-publish"]
            .iter()
            .collect();
        let app_publish_dir: path::PathBuf = [
            &self.config.madp_location,
            &format!(
                "data/csii-app-publish/{}/{}-{}",
                self.config.app_config.app_id,
                self.config.app_config.app_id,
                &self.config.pre_publish_config.version
            ),
        ]
        .iter()
        .collect();
        let default_publish_dir: path::PathBuf = [
            &self.config.madp_location,
            &format!(
                "data/csii-app-publish/{}/{}-default",
                self.config.app_config.app_id, self.config.app_config.app_id,
            ),
        ]
        .iter()
        .collect();
        let app_list_str = fs::read_to_string(publish_dir.join("_list.json")).unwrap();
        let app_list = serde_json::Value::from_str(&app_list_str).unwrap();
        match app_list[&self.config.app_config.app_id] {
            serde_json::Value::Object(_) => (),
            _ => panic!("任务执行失败:应用不存在!"),
        };

        let now = Local::now();
        let crash_path: path::PathBuf = [
            &self.config.madp_location,
            &format!(
                "data/csii-app-publish/{}/{}-default-crash-in-{}",
                self.config.app_config.app_id,
                self.config.app_config.app_id,
                now.timestamp()
            ),
        ]
        .iter()
        .collect();
        fs::create_dir(&crash_path).unwrap();
        println!("开始备份...");
        let options = CopyOptions::new();
        match move_dir(&default_publish_dir, &crash_path, &options) {
            Ok(_) => {
                println!("备份完成，备份地址为:");
                println!("{}", crash_path.to_string_lossy());
            }
            Err(err) => panic!("任务执行失败:{}发布失败!", err),
        };
        fs::create_dir(&default_publish_dir).unwrap();
        println!("开始复制文件...");

        let cp_options = CopyOptions::new();
        let cp_options = cp_options.content_only(true).clone();
        match copy(app_publish_dir, &default_publish_dir, &cp_options) {
            Ok(_) => (),
            Err(err) => panic!("任务执行失败:{}发布失败!", err),
        }
        println!("定时发版任务已完成");
    }
}
pub fn rollback(backup_map: &HashMap<String, String>) -> Result<(), io::Error> {
    for (file_name, origin_path) in backup_map.iter() {
        match fs::copy(file_name, origin_path) {
            Ok(_) => (),
            Err(err) => return Err(err),
        };
    }
    Ok(())
}
